Search code examples
cgccgcc-warning

dangerous relocation warning by gcc


i have a copy_object function which basicly just makes a copy of any object given a pointer to it and its size and i use it in a library i made here is the function

/// @brief dynamically allocates a copy of an object
/// @param obj_ptr a pointer to the object
/// @param obj_size the size of the object
/// @return a pointer to the copy
extern void *copy_object(void *obj_ptr , size_t obj_size){
    void *copy = calloc(1 , obj_size);
    if(!copy){
        return NULL;
    }

    memcpy(copy , obj_ptr , obj_size);

    return copy;
}

when compiling the library on windows theres no proplem , but when i compile it on wsl ubuntu 22.04.3 with gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) i get this error :

/usr/bin/ld: BFD (GNU Binutils for Ubuntu) 2.38 assertion fail ../../bfd/reloc.c:8580
c_datastructures/bin//liblinked_list.a(copy_object.o):copy_object.c:(.pdata+0x0): dangerous relocation: collect2: fatal error: ld terminated with signal 11 [Segmentation fault]
compilation terminated.

here is the code for the linked list in case it helps :

#include "../headers/copy_object.h"
#include <stdlib.h>
#include "../headers/linked_list.h"

struct node {
    struct node *prev;

    void *obj_ptr;
    size_t obj_size;
    free_func *free_obj;

    struct node *next;
};

struct linked_list {
    u64 node_no;
    node *first_node;
    node *last_node;
};

linked_list *new_linked_list(){
    return (linked_list *) calloc(1 , sizeof(linked_list));
}

void linked_list_free_node(node *node_ptr){
    if(!node_ptr){
        return;
    }

    free(node_ptr -> obj_ptr);
    free(node_ptr);
}

void free_linked_list_contents(linked_list *list_ptr){
    if(!list_ptr){
        return;
    }

    for(node *curr_node = list_ptr -> first_node , *tmp ; curr_node ; curr_node = tmp){
        tmp = curr_node -> next;
        linked_list_free_node(curr_node);
    }

    list_ptr -> first_node = NULL;
    list_ptr -> last_node = NULL;
    list_ptr -> node_no = 0;
}

datastruct_err destroy_linked_list(linked_list *list_ptr){
    if(!list_ptr){
        return  Invalid_Input;
    }

    if(list_ptr -> first_node){
        free_linked_list_contents(list_ptr);
    }

    free(list_ptr);
    return Success;
}

node *linked_list_create_node(void *obj_ptr , size_t obj_size , free_func *free_obj){
    if(!obj_ptr || !obj_size){
        return NULL;
    }

    node *ret = (node *) calloc(1 , sizeof(node));
    if(!ret){
        return NULL;
    }

    ret -> obj_ptr = copy_object(obj_ptr , obj_size);
    if(!ret -> obj_ptr){
        free(ret);
        return NULL;
    }

    ret -> obj_size = obj_size;

    if(free_obj){
        ret -> free_obj = free_obj;
    }else{
        ret -> free_obj = free;
    }

    return ret;
}

datastruct_err linked_list_add_node(void *obj_ptr , size_t obj_size , free_func *free_obj , linked_list *list_ptr){
    if(!obj_ptr || !list_ptr || !obj_size){
        return Invalid_Input;
    }

    node *new_node = linked_list_create_node(obj_ptr , obj_size , free_obj);
    if(!new_node){
        return Allocation_err;
    }

    if(!list_ptr -> first_node){
        list_ptr -> first_node = list_ptr -> last_node = new_node;
    }else{
        node *target = list_ptr -> last_node;
        list_ptr -> last_node = new_node;
        new_node -> prev = target;
        target -> next = new_node;
    }

    list_ptr -> node_no++;

    return Success;
}

node *linked_list_get_node(u64 index , linked_list *list_ptr){
    if(!list_ptr){
        return NULL;
    }

    if(index >= list_ptr -> node_no){
        return NULL;
    }

    u64 i = 0;
    node *ret = NULL;

    if(index <= list_ptr -> node_no / 2){
        for(ret = list_ptr -> first_node ; ret != NULL && i < index ; ret = ret -> next , i++){}
    }else{
        for(ret = list_ptr -> last_node  , i = list_ptr -> node_no - 1; ret && i > index ; ret = ret -> prev , i--){}
    }

    return ret;
}

datastruct_err linked_list_delete_node(u64 index , linked_list *list_ptr){
    if(!list_ptr){
        return Invalid_Input;
    }

    if(index >= list_ptr -> node_no){
        return Invalid_Input;
    }

    node *target = linked_list_get_node(index , list_ptr);

    if(index == 0){
        list_ptr -> first_node = list_ptr -> first_node -> next;
        if(list_ptr -> node_no == 1){
            list_ptr -> last_node = NULL;
        }else{
            target -> next -> prev = target -> prev;
        }
    }else{ 
        if(index == list_ptr -> node_no - 1){
            list_ptr -> last_node = list_ptr -> last_node -> prev;
        }else{
            target -> next -> prev = target -> prev;
        }
        target -> prev -> next = target -> next;
    }

    linked_list_free_node(target);

    list_ptr -> node_no--;

    return Success;
}

node *linked_list_get_first_node(linked_list *list_ptr){
    if(!list_ptr){
        return NULL;
    }

    return list_ptr -> first_node;
}

node *linked_list_get_last_node(linked_list *list_ptr){
    if(!list_ptr){
        return NULL;
    }

    return list_ptr -> last_node;
}

u64 linked_list_get_node_no(linked_list *list_ptr){
    if(!list_ptr){
        return 0;
    }

    return list_ptr -> node_no;
}

node *linked_list_get_prev_node(node *node_ptr){
    if(!node_ptr){
        return NULL;
    }

    return node_ptr -> prev;
}

node *linked_list_get_next_node(node *node_ptr){
    if(!node_ptr){
        return NULL;
    }

    return node_ptr -> next;
}

void *linked_list_get_obj_ptr(node *node_ptr){
    if(!node_ptr){
        return NULL;
    }

    return node_ptr -> obj_ptr;
}

size_t linked_list_get_obj_size(node *node_ptr){
    if(!node_ptr){
        return 0;
    }

    return node_ptr -> obj_size;
}

i looked at the code as i have written it a long time ago but there's no relocations in the first place it just copies memory


Solution

  • That is a linker error, so it is possible that it has nothing do with your code. But with how you compile it.

    The most common reason for that problem is then you have object files compiled by different compilers. So as first step, make sure you delete all .o files you have. Do make clean or whatever is appropriate with your build system. Once there are only source files remain - try compiling again.