[BACK]Return to testplug3.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / ld

Annotation of src/external/gpl3/binutils.old/dist/ld/testplug3.c, Revision 1.1.1.2

1.1       christos    1: /* Test plugin for the GNU linker.  Check non-object IR file and calling
                      2:    release_input_file from onclaim_file.
1.1.1.2 ! christos    3:    Copyright (C) 2015-2016 Free Software Foundation, Inc.
1.1       christos    4:
                      5:    This file is part of the GNU Binutils.
                      6:
                      7:    This program is free software; you can redistribute it and/or modify
                      8:    it under the terms of the GNU General Public License as published by
                      9:    the Free Software Foundation; either version 3 of the License, or
                     10:    (at your option) any later version.
                     11:
                     12:    This program is distributed in the hope that it will be useful,
                     13:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:    GNU General Public License for more details.
                     16:
                     17:    You should have received a copy of the GNU General Public License
                     18:    along with this program; if not, write to the Free Software
                     19:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
                     20:    MA 02110-1301, USA.  */
                     21:
                     22: #include "sysdep.h"
                     23: #include "bfd.h"
                     24: #include "plugin-api.h"
                     25: #include "filenames.h"
                     26: /* For ARRAY_SIZE macro only - we don't link the library itself.  */
                     27: #include "libiberty.h"
                     28:
                     29: extern enum ld_plugin_status onload (struct ld_plugin_tv *tv);
                     30: static enum ld_plugin_status onclaim_file (const struct ld_plugin_input_file *file,
                     31:                                int *claimed);
                     32: static enum ld_plugin_status onall_symbols_read (void);
                     33: static enum ld_plugin_status oncleanup (void);
                     34:
                     35: /* Helper for calling plugin api message function.  */
                     36: #define TV_MESSAGE if (tv_message) (*tv_message)
                     37:
                     38: /* Struct for recording files to claim / files claimed.  */
                     39: typedef struct claim_file
                     40: {
                     41:   struct claim_file *next;
                     42:   struct ld_plugin_input_file file;
                     43:   bfd_boolean claimed;
                     44:   struct ld_plugin_symbol *symbols;
                     45:   int n_syms_allocated;
                     46:   int n_syms_used;
                     47: } claim_file_t;
                     48:
                     49: /* Types of things that can be added at all symbols read time.  */
                     50: typedef enum addfile_enum
                     51: {
                     52:   ADD_FILE,
                     53:   ADD_LIB,
                     54:   ADD_DIR
                     55: } addfile_enum_t;
                     56:
                     57: /* Struct for recording files to add to final link.  */
                     58: typedef struct add_file
                     59: {
                     60:   struct add_file *next;
                     61:   const char *name;
                     62:   addfile_enum_t type;
                     63: } add_file_t;
                     64:
                     65: /* Helper macro for defining array of transfer vector tags and names.  */
                     66: #define ADDENTRY(tag) { tag, #tag }
                     67:
                     68: /* Struct for looking up human-readable versions of tag names.  */
                     69: typedef struct tag_name
                     70: {
                     71:   enum ld_plugin_tag tag;
                     72:   const char *name;
                     73: } tag_name_t;
                     74:
                     75: /* Array of all known tags and their names.  */
                     76: static const tag_name_t tag_names[] =
                     77: {
                     78:   ADDENTRY(LDPT_NULL),
                     79:   ADDENTRY(LDPT_API_VERSION),
                     80:   ADDENTRY(LDPT_GOLD_VERSION),
                     81:   ADDENTRY(LDPT_LINKER_OUTPUT),
                     82:   ADDENTRY(LDPT_OPTION),
                     83:   ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK),
                     84:   ADDENTRY(LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK),
                     85:   ADDENTRY(LDPT_REGISTER_CLEANUP_HOOK),
                     86:   ADDENTRY(LDPT_ADD_SYMBOLS),
                     87:   ADDENTRY(LDPT_GET_SYMBOLS),
                     88:   ADDENTRY(LDPT_GET_SYMBOLS_V2),
                     89:   ADDENTRY(LDPT_ADD_INPUT_FILE),
                     90:   ADDENTRY(LDPT_MESSAGE),
                     91:   ADDENTRY(LDPT_GET_INPUT_FILE),
                     92:   ADDENTRY(LDPT_GET_VIEW),
                     93:   ADDENTRY(LDPT_RELEASE_INPUT_FILE),
                     94:   ADDENTRY(LDPT_ADD_INPUT_LIBRARY),
                     95:   ADDENTRY(LDPT_OUTPUT_NAME),
                     96:   ADDENTRY(LDPT_SET_EXTRA_LIBRARY_PATH),
                     97:   ADDENTRY(LDPT_GNU_LD_VERSION)
                     98: };
                     99:
                    100: /* Function pointers to cache hooks passed at onload time.  */
                    101: static ld_plugin_register_claim_file tv_register_claim_file = 0;
                    102: static ld_plugin_register_all_symbols_read tv_register_all_symbols_read = 0;
                    103: static ld_plugin_register_cleanup tv_register_cleanup = 0;
                    104: static ld_plugin_add_symbols tv_add_symbols = 0;
                    105: static ld_plugin_get_symbols tv_get_symbols = 0;
                    106: static ld_plugin_get_symbols tv_get_symbols_v2 = 0;
                    107: static ld_plugin_add_input_file tv_add_input_file = 0;
                    108: static ld_plugin_message tv_message = 0;
                    109: static ld_plugin_get_input_file tv_get_input_file = 0;
                    110: static ld_plugin_get_view tv_get_view = 0;
                    111: static ld_plugin_release_input_file tv_release_input_file = 0;
                    112: static ld_plugin_add_input_library tv_add_input_library = 0;
                    113: static ld_plugin_set_extra_library_path tv_set_extra_library_path = 0;
                    114:
                    115: /* Other cached info from the transfer vector.  */
                    116: static enum ld_plugin_output_file_type linker_output;
                    117: static const char *output_name;
                    118:
                    119: /* Behaviour control flags set by plugin options.  */
                    120: static enum ld_plugin_status onload_ret = LDPS_OK;
                    121: static enum ld_plugin_status claim_file_ret = LDPS_OK;
                    122: static enum ld_plugin_status all_symbols_read_ret = LDPS_OK;
                    123: static enum ld_plugin_status cleanup_ret = LDPS_OK;
                    124: static bfd_boolean register_claimfile_hook = TRUE;
                    125: static bfd_boolean register_allsymbolsread_hook = FALSE;
                    126: static bfd_boolean register_cleanup_hook = FALSE;
                    127: static bfd_boolean dumpresolutions = FALSE;
                    128:
                    129: /* The master list of all claimable/claimed files.  */
                    130: static claim_file_t *claimfiles_list = NULL;
                    131:
                    132: /* We keep a tail pointer for easy linking on the end.  */
                    133: static claim_file_t **claimfiles_tail_chain_ptr = &claimfiles_list;
                    134:
                    135: /* The last claimed file added to the list, for receiving syms.  */
                    136: static claim_file_t *last_claimfile = NULL;
                    137:
                    138: /* The master list of all files to add to the final link.  */
                    139: static add_file_t *addfiles_list = NULL;
                    140:
                    141: /* We keep a tail pointer for easy linking on the end.  */
                    142: static add_file_t **addfiles_tail_chain_ptr = &addfiles_list;
                    143:
                    144: /* Add a new claimfile on the end of the chain.  */
                    145: static enum ld_plugin_status
                    146: record_claim_file (const char *file, off_t filesize)
                    147: {
                    148:   claim_file_t *newfile;
                    149:
                    150:   newfile = malloc (sizeof *newfile);
                    151:   if (!newfile)
                    152:     return LDPS_ERR;
                    153:   memset (newfile, 0, sizeof *newfile);
                    154:   /* Only setup for now is remembering the name to look for.  */
                    155:   newfile->file.name = file;
                    156:   newfile->file.filesize = filesize;
                    157:   /* Chain it on the end of the list.  */
                    158:   *claimfiles_tail_chain_ptr = newfile;
                    159:   claimfiles_tail_chain_ptr = &newfile->next;
                    160:   /* Record it as active for receiving symbols to register.  */
                    161:   last_claimfile = newfile;
                    162:   return LDPS_OK;
                    163: }
                    164:
                    165: /* Add a new addfile on the end of the chain.  */
                    166: static enum ld_plugin_status
                    167: record_add_file (const char *file, addfile_enum_t type)
                    168: {
                    169:   add_file_t *newfile;
                    170:
                    171:   newfile = malloc (sizeof *newfile);
                    172:   if (!newfile)
                    173:     return LDPS_ERR;
                    174:   newfile->next = NULL;
                    175:   newfile->name = file;
                    176:   newfile->type = type;
                    177:   /* Chain it on the end of the list.  */
                    178:   *addfiles_tail_chain_ptr = newfile;
                    179:   addfiles_tail_chain_ptr = &newfile->next;
                    180:   return LDPS_OK;
                    181: }
                    182:
                    183: /* Parse a command-line argument string into a symbol definition.
                    184:    Symbol-strings follow the colon-separated format:
                    185:        NAME:VERSION:def:vis:size:COMDATKEY
                    186:    where the fields in capitals are strings and those in lower
                    187:    case are integers.  We don't allow to specify a resolution as
                    188:    doing so is not meaningful when calling the add symbols hook.  */
                    189: static enum ld_plugin_status
                    190: parse_symdefstr (const char *str, struct ld_plugin_symbol *sym)
                    191: {
                    192:   int n;
                    193:   long long size;
                    194:   const char *colon1, *colon2, *colon5;
                    195:
                    196:   /* Locate the colons separating the first two strings.  */
                    197:   colon1 = strchr (str, ':');
                    198:   if (!colon1)
                    199:     return LDPS_ERR;
                    200:   colon2 = strchr (colon1+1, ':');
                    201:   if (!colon2)
                    202:     return LDPS_ERR;
                    203:   /* Name must not be empty (version may be).  */
                    204:   if (colon1 == str)
                    205:     return LDPS_ERR;
                    206:
                    207:   /* The fifth colon and trailing comdat key string are optional,
                    208:      but the intermediate ones must all be present.  */
                    209:   colon5 = strchr (colon2+1, ':');     /* Actually only third so far.  */
                    210:   if (!colon5)
                    211:     return LDPS_ERR;
                    212:   colon5 = strchr (colon5+1, ':');     /* Hopefully fourth now.  */
                    213:   if (!colon5)
                    214:     return LDPS_ERR;
                    215:   colon5 = strchr (colon5+1, ':');     /* Optional fifth now.  */
                    216:
                    217:   /* Finally we'll use sscanf to parse the numeric fields, then
                    218:      we'll split out the strings which we need to allocate separate
                    219:      storage for anyway so that we can add nul termination.  */
                    220:   n = sscanf (colon2 + 1, "%i:%i:%lli", &sym->def, &sym->visibility, &size);
                    221:   if (n != 3)
                    222:     return LDPS_ERR;
                    223:
                    224:   /* Parsed successfully, so allocate strings and fill out fields.  */
                    225:   sym->size = size;
                    226:   sym->resolution = LDPR_UNKNOWN;
                    227:   sym->name = malloc (colon1 - str + 1);
                    228:   if (!sym->name)
                    229:     return LDPS_ERR;
                    230:   memcpy (sym->name, str, colon1 - str);
                    231:   sym->name[colon1 - str] = '\0';
                    232:   if (colon2 > (colon1 + 1))
                    233:     {
                    234:       sym->version = malloc (colon2 - colon1);
                    235:       if (!sym->version)
                    236:        return LDPS_ERR;
                    237:       memcpy (sym->version, colon1 + 1, colon2 - (colon1 + 1));
                    238:       sym->version[colon2 - (colon1 + 1)] = '\0';
                    239:     }
                    240:   else
                    241:     sym->version = NULL;
                    242:   if (colon5 && colon5[1])
                    243:     {
                    244:       sym->comdat_key = malloc (strlen (colon5 + 1) + 1);
                    245:       if (!sym->comdat_key)
                    246:        return LDPS_ERR;
                    247:       strcpy (sym->comdat_key, colon5 + 1);
                    248:     }
                    249:   else
                    250:     sym->comdat_key = 0;
                    251:   return LDPS_OK;
                    252: }
                    253:
                    254: /* Record a symbol to be added for the last-added claimfile.  */
                    255: static enum ld_plugin_status
                    256: record_claimed_file_symbol (const char *symdefstr)
                    257: {
                    258:   struct ld_plugin_symbol sym;
                    259:
                    260:   /* Can't add symbols except as belonging to claimed files.  */
                    261:   if (!last_claimfile)
                    262:     return LDPS_ERR;
                    263:
                    264:   /* If string doesn't parse correctly, give an error.  */
                    265:   if (parse_symdefstr (symdefstr, &sym) != LDPS_OK)
                    266:     return LDPS_ERR;
                    267:
                    268:   /* Check for enough space, resize array if needed, and add it.  */
                    269:   if (last_claimfile->n_syms_allocated == last_claimfile->n_syms_used)
                    270:     {
                    271:       int new_n_syms = last_claimfile->n_syms_allocated
                    272:                        ? 2 * last_claimfile->n_syms_allocated
                    273:                        : 10;
                    274:       last_claimfile->symbols = realloc (last_claimfile->symbols,
                    275:                        new_n_syms * sizeof *last_claimfile->symbols);
                    276:       if (!last_claimfile->symbols)
                    277:        return LDPS_ERR;
                    278:       last_claimfile->n_syms_allocated = new_n_syms;
                    279:     }
                    280:   last_claimfile->symbols[last_claimfile->n_syms_used++] = sym;
                    281:
                    282:   return LDPS_OK;
                    283: }
                    284:
                    285: /* Records the status to return from one of the registered hooks.  */
                    286: static enum ld_plugin_status
                    287: set_ret_val (const char *whichval, enum ld_plugin_status retval)
                    288: {
                    289:   if (!strcmp ("onload", whichval))
                    290:     onload_ret = retval;
                    291:   else if (!strcmp ("claimfile", whichval))
                    292:     claim_file_ret = retval;
                    293:   else if (!strcmp ("allsymbolsread", whichval))
                    294:     all_symbols_read_ret = retval;
                    295:   else if (!strcmp ("cleanup", whichval))
                    296:     cleanup_ret = retval;
                    297:   else
                    298:     return LDPS_ERR;
                    299:   return LDPS_OK;
                    300: }
                    301:
                    302: /* Records hooks which should be registered.  */
                    303: static enum ld_plugin_status
                    304: set_register_hook (const char *whichhook, bfd_boolean yesno)
                    305: {
                    306:   if (!strcmp ("claimfile", whichhook))
                    307:     register_claimfile_hook = yesno;
                    308:   else if (!strcmp ("allsymbolsread", whichhook))
                    309:     register_allsymbolsread_hook = yesno;
                    310:   else if (!strcmp ("cleanup", whichhook))
                    311:     register_cleanup_hook = yesno;
                    312:   else
                    313:     return LDPS_ERR;
                    314:   return LDPS_OK;
                    315: }
                    316:
                    317: /* Determine type of plugin option and pass to individual parsers.  */
                    318: static enum ld_plugin_status
                    319: parse_option (const char *opt)
                    320: {
                    321:   if (!strncmp ("fail", opt, 4))
                    322:     return set_ret_val (opt + 4, LDPS_ERR);
                    323:   else if (!strncmp ("pass", opt, 4))
                    324:     return set_ret_val (opt + 4, LDPS_OK);
                    325:   else if (!strncmp ("register", opt, 8))
                    326:     return set_register_hook (opt + 8, TRUE);
                    327:   else if (!strncmp ("noregister", opt, 10))
                    328:     return set_register_hook (opt + 10, FALSE);
                    329:   else if (!strncmp ("claim:", opt, 6))
                    330:     return record_claim_file (opt + 6, 0);
                    331:   else if (!strncmp ("sym:", opt, 4))
                    332:     return record_claimed_file_symbol (opt + 4);
                    333:   else if (!strncmp ("add:", opt, 4))
                    334:     return record_add_file (opt + 4, ADD_FILE);
                    335:   else if (!strncmp ("lib:", opt, 4))
                    336:     return record_add_file (opt + 4, ADD_LIB);
                    337:   else if (!strncmp ("dir:", opt, 4))
                    338:     return record_add_file (opt + 4, ADD_DIR);
                    339:   else if (!strcmp ("dumpresolutions", opt))
                    340:     dumpresolutions = TRUE;
                    341:   else
                    342:     return LDPS_ERR;
                    343:   return LDPS_OK;
                    344: }
                    345:
                    346: /* Handle/record information received in a transfer vector entry.  */
                    347: static enum ld_plugin_status
                    348: parse_tv_tag (struct ld_plugin_tv *tv)
                    349: {
                    350: #define SETVAR(x) x = tv->tv_u.x
                    351:   switch (tv->tv_tag)
                    352:     {
                    353:       case LDPT_OPTION:
                    354:        return parse_option (tv->tv_u.tv_string);
                    355:       case LDPT_NULL:
                    356:       case LDPT_GOLD_VERSION:
                    357:       case LDPT_GNU_LD_VERSION:
                    358:       case LDPT_API_VERSION:
                    359:       default:
                    360:        break;
                    361:       case LDPT_OUTPUT_NAME:
                    362:        output_name = tv->tv_u.tv_string;
                    363:        break;
                    364:       case LDPT_LINKER_OUTPUT:
                    365:        linker_output = tv->tv_u.tv_val;
                    366:        break;
                    367:       case LDPT_REGISTER_CLAIM_FILE_HOOK:
                    368:        SETVAR(tv_register_claim_file);
                    369:        break;
                    370:       case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
                    371:        SETVAR(tv_register_all_symbols_read);
                    372:        break;
                    373:       case LDPT_REGISTER_CLEANUP_HOOK:
                    374:        SETVAR(tv_register_cleanup);
                    375:        break;
                    376:       case LDPT_ADD_SYMBOLS:
                    377:        SETVAR(tv_add_symbols);
                    378:        break;
                    379:       case LDPT_GET_SYMBOLS:
                    380:        SETVAR(tv_get_symbols);
                    381:        break;
                    382:       case LDPT_GET_SYMBOLS_V2:
                    383:        tv_get_symbols_v2 = tv->tv_u.tv_get_symbols;
                    384:        break;
                    385:       case LDPT_ADD_INPUT_FILE:
                    386:        SETVAR(tv_add_input_file);
                    387:        break;
                    388:       case LDPT_MESSAGE:
                    389:        SETVAR(tv_message);
                    390:        break;
                    391:       case LDPT_GET_INPUT_FILE:
                    392:        SETVAR(tv_get_input_file);
                    393:        break;
                    394:       case LDPT_GET_VIEW:
                    395:        SETVAR(tv_get_view);
                    396:        break;
                    397:       case LDPT_RELEASE_INPUT_FILE:
                    398:        SETVAR(tv_release_input_file);
                    399:        break;
                    400:       case LDPT_ADD_INPUT_LIBRARY:
                    401:        SETVAR(tv_add_input_library);
                    402:        break;
                    403:       case LDPT_SET_EXTRA_LIBRARY_PATH:
                    404:        SETVAR(tv_set_extra_library_path);
                    405:        break;
                    406:     }
                    407: #undef SETVAR
                    408:   return LDPS_OK;
                    409: }
                    410:
                    411: /* Standard plugin API entry point.  */
                    412: enum ld_plugin_status
                    413: onload (struct ld_plugin_tv *tv)
                    414: {
                    415:   enum ld_plugin_status rv;
                    416:
                    417:   /* This plugin does nothing but dump the tv array.  It would
                    418:      be an error if this function was called without one.  */
                    419:   if (!tv)
                    420:     return LDPS_ERR;
                    421:
                    422:   /* First entry should always be LDPT_MESSAGE, letting us get
                    423:      hold of it easily so we can send output straight away.  */
                    424:   if (tv[0].tv_tag == LDPT_MESSAGE)
                    425:     tv_message = tv[0].tv_u.tv_message;
                    426:
                    427:   do
                    428:     if ((rv = parse_tv_tag (tv)) != LDPS_OK)
                    429:       return rv;
                    430:   while ((tv++)->tv_tag != LDPT_NULL);
                    431:
                    432:   /* Register hooks only if instructed by options.  */
                    433:   if (register_claimfile_hook)
                    434:     {
                    435:       if (!tv_register_claim_file)
                    436:        {
                    437:          TV_MESSAGE (LDPL_FATAL, "No register_claim_file hook");
                    438:          fflush (NULL);
                    439:          return LDPS_ERR;
                    440:        }
                    441:       (*tv_register_claim_file) (onclaim_file);
                    442:     }
                    443:   if (register_allsymbolsread_hook)
                    444:     {
                    445:       if (!tv_register_all_symbols_read)
                    446:        {
                    447:          TV_MESSAGE (LDPL_FATAL, "No register_all_symbols_read hook");
                    448:          fflush (NULL);
                    449:          return LDPS_ERR;
                    450:        }
                    451:       (*tv_register_all_symbols_read) (onall_symbols_read);
                    452:     }
                    453:   if (register_cleanup_hook)
                    454:     {
                    455:       if (!tv_register_cleanup)
                    456:        {
                    457:          TV_MESSAGE (LDPL_FATAL, "No register_cleanup hook");
                    458:          fflush (NULL);
                    459:          return LDPS_ERR;
                    460:        }
                    461:       (*tv_register_cleanup) (oncleanup);
                    462:     }
                    463:
                    464:   /* Claim testsuite/ld-plugin/func.c, standalone or in a library.  Its
                    465:      size must be SIZE_OF_FUNC_C bytes.  */
                    466: #define SIZE_OF_FUNC_C 248
                    467:   if (onload_ret == LDPS_OK
                    468:       && (record_claim_file ("func.c", SIZE_OF_FUNC_C) != LDPS_OK
                    469:          || record_claimed_file_symbol ("func::0:0:0") != LDPS_OK
                    470:          || record_claimed_file_symbol ("_func::0:0:0") != LDPS_OK
                    471:          || record_claim_file ("libfunc.a", SIZE_OF_FUNC_C) != LDPS_OK
                    472:          || record_claimed_file_symbol ("func::0:0:0") != LDPS_OK
                    473:          || record_claimed_file_symbol ("_func::0:0:0") != LDPS_OK))
                    474:     onload_ret = LDPS_ERR;
                    475:
                    476:   return onload_ret;
                    477: }
                    478:
                    479: char *
                    480: xstrdup (const char *s)
                    481: {
                    482:   size_t len = strlen (s) + 1;
                    483:   char *ret = malloc (len + 1);
                    484:   return (char *) memcpy (ret, s, len);
                    485: }
                    486:
                    487: /* Standard plugin API registerable hook.  */
                    488: static enum ld_plugin_status
                    489: onclaim_file (const struct ld_plugin_input_file *file, int *claimed)
                    490: {
                    491:   /* Let's see if we want to claim this file.  */
                    492:   claim_file_t *claimfile = claimfiles_list;
                    493:   size_t len = strlen (file->name);
                    494:   char *name = xstrdup (file->name);
                    495:   char *p = name + len;
                    496:   bfd_boolean islib;
                    497:
                    498:   /* Only match the file name without the directory part.  */
                    499:   islib = *p == 'a' && *(p - 1) == '.';
                    500:   for (; p != name; p--)
                    501:     if (IS_DIR_SEPARATOR (*p))
                    502:       {
                    503:        p++;
                    504:        break;
                    505:       }
                    506:
                    507:   while (claimfile)
                    508:     {
                    509:       /* Claim the file only if the file name and size match and don't
                    510:         match the whole library.  */
                    511:       if (!strcmp (p, claimfile->file.name)
                    512:          && claimfile->file.filesize == file->filesize
                    513:          && (!islib || file->offset != 0))
                    514:        break;
                    515:       claimfile = claimfile->next;
                    516:     }
                    517:
                    518:   free (name);
                    519:
                    520:   /* If we decided to claim it, record that fact, and add any symbols
                    521:      that were defined for it by plugin options.  */
                    522:   *claimed = (claimfile != 0);
                    523:   if (claimfile)
                    524:     {
                    525:       char buffer[30];
                    526:       int fd;
                    527:
                    528:       TV_MESSAGE (LDPL_INFO, "Claimed: %s [@%ld/%ld]", file->name,
                    529:                  (long)file->offset, (long)file->filesize);
                    530:
                    531:       claimfile->claimed = TRUE;
                    532:       claimfile->file = *file;
                    533:       if (claimfile->n_syms_used && !tv_add_symbols)
                    534:        claim_file_ret = LDPS_ERR;
                    535:       else if (claimfile->n_syms_used)
                    536:        claim_file_ret = (*tv_add_symbols) (claimfile->file.handle,
                    537:                                            claimfile->n_syms_used,
                    538:                                            claimfile->symbols);
                    539:
                    540:       fd = claimfile->file.fd;
                    541:       name = xstrdup (claimfile->file.name);
                    542:       claim_file_ret = tv_release_input_file (claimfile->file.handle);
                    543:       if (claim_file_ret != LDPS_OK)
                    544:        {
                    545:          free (name);
                    546:          return claim_file_ret;
                    547:        }
                    548:       if (read (fd, buffer, sizeof (buffer)) >= 0)
                    549:        {
                    550:          claim_file_ret = LDPS_ERR;
                    551:          TV_MESSAGE (LDPL_FATAL, "Unreleased file descriptor on: %s", name);
                    552:        }
                    553:       free (name);
                    554:     }
                    555:
                    556:   return claim_file_ret;
                    557: }
                    558:
                    559: /* Standard plugin API registerable hook.  */
                    560: static enum ld_plugin_status
                    561: onall_symbols_read (void)
                    562: {
                    563:   static const char *resolutions[] =
                    564:     {
                    565:       "LDPR_UNKNOWN",
                    566:       "LDPR_UNDEF",
                    567:       "LDPR_PREVAILING_DEF",
                    568:       "LDPR_PREVAILING_DEF_IRONLY",
                    569:       "LDPR_PREEMPTED_REG",
                    570:       "LDPR_PREEMPTED_IR",
                    571:       "LDPR_RESOLVED_IR",
                    572:       "LDPR_RESOLVED_EXEC",
                    573:       "LDPR_RESOLVED_DYN",
                    574:       "LDPR_PREVAILING_DEF_IRONLY_EXP",
                    575:     };
                    576:   claim_file_t *claimfile = dumpresolutions ? claimfiles_list : NULL;
                    577:   add_file_t *addfile = addfiles_list;
                    578:   TV_MESSAGE (LDPL_INFO, "hook called: all symbols read.");
                    579:   for ( ; claimfile; claimfile = claimfile->next)
                    580:     {
                    581:       enum ld_plugin_status rv;
                    582:       int n;
                    583:       if (claimfile->n_syms_used && !tv_get_symbols_v2)
                    584:        return LDPS_ERR;
                    585:       else if (!claimfile->n_syms_used)
                    586:         continue;
                    587:       else if (!claimfile->file.handle)
                    588:         continue;
                    589:       rv = tv_get_symbols_v2 (claimfile->file.handle, claimfile->n_syms_used,
                    590:                              claimfile->symbols);
                    591:       if (rv != LDPS_OK)
                    592:        return rv;
                    593:       for (n = 0; n < claimfile->n_syms_used; n++)
                    594:        TV_MESSAGE (LDPL_INFO, "Sym: '%s%s%s' Resolution: %s",
                    595:                    claimfile->symbols[n].name,
                    596:                    claimfile->symbols[n].version ? "@" : "",
                    597:                    (claimfile->symbols[n].version
                    598:                     ? claimfile->symbols[n].version : ""),
                    599:                    resolutions[claimfile->symbols[n].resolution]);
                    600:     }
                    601:   for ( ; addfile ; addfile = addfile->next)
                    602:     {
                    603:       enum ld_plugin_status rv;
                    604:       if (addfile->type == ADD_LIB && tv_add_input_library)
                    605:        rv = (*tv_add_input_library) (addfile->name);
                    606:       else if (addfile->type == ADD_FILE && tv_add_input_file)
                    607:        rv = (*tv_add_input_file) (addfile->name);
                    608:       else if (addfile->type == ADD_DIR && tv_set_extra_library_path)
                    609:        rv = (*tv_set_extra_library_path) (addfile->name);
                    610:       else
                    611:        rv = LDPS_ERR;
                    612:       if (rv != LDPS_OK)
                    613:        return rv;
                    614:     }
                    615:   fflush (NULL);
                    616:   return all_symbols_read_ret;
                    617: }
                    618:
                    619: /* Standard plugin API registerable hook.  */
                    620: static enum ld_plugin_status
                    621: oncleanup (void)
                    622: {
                    623:   TV_MESSAGE (LDPL_INFO, "hook called: cleanup.");
                    624:   fflush (NULL);
                    625:   return cleanup_ret;
                    626: }

CVSweb <webmaster@jp.NetBSD.org>