2016-02-28 1 views
0

Je développe un système embarqué avec GCC, et je voudrais utiliser seulement quelques symboles de libc. Par exemple, je voudrais utiliser le memcpy de base, memmove, memset, strlen, strcpy, etc Cependant, je voudrais fournir ma propre fonction printf (plus petite), donc je ne veux pas libc pour priver printf. Je ne veux pas d'allocation dynamique sur cette plate-forme, donc je ne veux pas que malloc se résolve du tout.Lier uniquement certains symboles d'une bibliothèque

Existe-t-il un moyen de dire à GCC "ne fournir que ces symboles" à partir de libc?

éditer: Pour être clair, je demande si je ne peux fournir que quelques symboles spécifiques à partir d'une bibliothèque, pas seulement remplacer une fonction de bibliothèque avec ma propre implémentation. Si le code utilise un symbole qui est dans la bibliothèque mais non spécifié, l'éditeur de liens doit échouer avec "symbole non résolu". Si une autre question explique comment faire cela, je ne l'ai pas encore vu.

+0

[question connexe] (http://stackoverflow.com/questions/29391965/what-is-partial-linking-in-gnu-linker) et [une autre question connexe] (http://stackoverflow.com/questions/270984/g-partial-linking -file-of-archives) – Kenney

+1

Copie possible de [Comment remplacer la fonction de bibliothèque standard C?] (Http://stackoverflow.com/questions/9107259/how-to-replace-c- standard-library-function) –

+0

Je ne considère pas cela comme un doublon, car ma question est "puis-je dire à l'éditeur de liens d'utiliser uniquement un sous-ensemble de symboles d'une bibliothèque" et non "puis-je remplacer cette fonction spécifique."La principale différence est que dans ma question, l'éditeur de liens devrait renflouer avec une erreur si un symbole qui n'a pas été explicitement nommé à partir de la bibliothèque est utilisé – FazJaxton

Répondre

-1

La solution la plus simple est probablement d'utiliser une enveloppe qui définit les symboles et les résout à l'exécution en utilisant dlfcn:

#include <dlfcn.h> 

void* (*memcpy)(void *dest, const void *src, size_t n); 
char* (*strncpy)(char *dest, const char *src, size_t n); 
... 

void init_symbols (void) { 
    void *handle = dlopen("/lib/libc.so.6", RTLD_LAZY); 

    memcpy = dlsym(handle, "memcpy"); 
    strncpy = dlsym(handle, "strncpy"); 
    ... 
} 

et lier votre binaire avec -nostdlib. Cela vous donne le meilleur contrôle sur les symboles à utiliser de quelle source.

+0

La question est balisée, il n'y a probablement pas de système de fichiers disponible est clairement après le rétrécissement du code, qui est un indice clair.) Comment pensez-vous que le chargement dynamique d'une bibliothèque fonctionnerait? – Olaf

1

Cela devrait se faire "automatiquement" tant que votre configuration de libc et de linker le supporte. Vous n'avez pas dit quelle est votre plateforme, donc here is one where it does work. Donc, créons un exemple stupide en utilisant snprintf.

/* 
* main.c 
*/ 
#include <stdio.h> 

int main(int argc, char **argv) { 
    char l[100]; 
    snprintf(l, 100, "%s %d\n", argv[0], argc); 
    return 0; 
} 

essayer de compiler et de le lier

$ CC=/opt/gcc-arm-none-eabi-4_7-2013q3/bin/arm-none-eabi-gcc 
$ CFLAGS="-mcpu=arm926ej-s -Wall -Wextra -O6" 
$ LDFLAGS="-nostartfiles -L. -Wl,--gc-sections,-emain" 
$ $CC $CFLAGS -c main.c -o main.o 
$ $CC $LDFLAGS main.o -o example 
/opt/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-sbrkr.o): In function `_sbrk_r': 
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk' 
collect2: error: ld returned 1 exit status 

Il a besoin _sbrk parce newlib *printf fonctions utilisent malloc qui a besoin d'un moyen d'allouer de la mémoire du système. Donnons-lui un mannequin.

/* 
* sbrk.c 
*/ 
#include <stdint.h> 
#include <unistd.h> 
void *_sbrk(intptr_t increment) { 
    return 0; 
} 

et compiler

$ $CC $CFLAGS -c sbrk.c -o sbrk.o 
$ $CC $LDFLAGS -Wl,-Map,"sbrk.map" main.o sbrk.o -o with-sbrk 
$ /opt/gcc-arm-none-eabi-4_7-2013q3/bin/arm-none-eabi-size with-sbrk 
    text data  bss  dec  hex filename 
    28956 2164  56 31176 79c8 with-sbrk 

Eh bien, c'est la raison pour laquelle vous souhaitez vous débarrasser de printf et les amis, est-ce pas? Maintenant, remplacez snprintf avec notre fonction

/* 
* replace.c 
*/ 
#include <stdio.h> 
#include <string.h> 
int snprintf(char *str, size_t size, const char *format, ...) { 
    return strlen(format); 
} 

compilez

$ $CC $CFLAGS -c replace.c -o replace.o 
$ $CC $LDFLAGS -Wl,-Map,"replace.map" main.o replace.o -o with-replace 
$ /opt/gcc-arm-none-eabi-4_7-2013q3/bin/arm-none-eabi-size with-sbrk 
    text data  bss  dec  hex filename 
    180  0  0  180  b4 with-replace 

Notez que nous n'avons pas utilisé le talon _sbrk du tout. Tant que vous ne fournissez pas _sbrk, vous pouvez être sûr que malloc n'est pas (ne peut pas être) lié et utilisé.

+0

Merci pour une réponse complète.Et bien deviner, j'utilise bras-none-eabi- avec newlib. :) – FazJaxton