Q:

Restful linking of existing resources

I don't think my setup is in any way unique, but I can't seem to find much information on the topic. I have a User entity. A user can have many Roles. The roles are pre-defined entities in the system and the client cannot create new roles. However a client can add or remove Roles from a User. I have a few ideas for how to implement linking a Role to a User this but I'm not sure which is the best option.
GET /users/1/roles returns a collection like:
[
  {
    "id":1,
    "name": "ACTIVE_USER"
  },
  {
    "id":2,
    "name": "ADMIN"
  }
]

Here are the options I've considered so far
1. roleId in body
POST /users/1/roles
{
  "roleId":1
}

2. role id in url
POST /users/1/roles/1
3. separate user-roles endpoint
POST /user-roles
{
    "userId":1,
    "roleId":1
}

4. same format as GET /roles returns
POST /user/1/roles
{
  "id":1        
}

A:

The roles are pre-defined entities in the system and the client cannot create new roles

I would advise against any of your options since they all do a POST request.
Remember the roles are predefined, you're not creating a new role so a POST request would be out of place.
Instead, since every user has a list of roles (may or may not be an empty list) I would simply do a PATCH request to update that list of roles with a new role. Remember PUT is create/replace, PATCH is "update"
A possible scenario could be that you can add and remove roles from a user. So I'd suggest you add an action parameter to the request body:
PATCH /users/1

[
  {"action": "add", "path": "/roles", "roleId": 1}
]

to add a role to a user. For removing you'd naturally replace add with remove.
See this page if you are curious where the usage of {"action": "add", "path": "/roles", "roleId": 1} comes from

