Print this page
10366 ld(1) should support GNU-style linker sets
10581 ld(1) should know kernel modules are a thing

*** 101,122 **** static Setstate Bdflag = SET_UNKNOWN; static Setstate zfwflag = SET_UNKNOWN; static Boolean aflag = FALSE; static Boolean bflag = FALSE; - static Boolean rflag = FALSE; static Boolean sflag = FALSE; static Boolean zinflag = FALSE; static Boolean zlflag = FALSE; static Boolean Bgflag = FALSE; static Boolean Blflag = FALSE; static Boolean Beflag = FALSE; static Boolean Bsflag = FALSE; static Boolean Dflag = FALSE; - static Boolean Gflag = FALSE; static Boolean Vflag = FALSE; /* * ztflag's state is set by pointing it to the matching string: * text | textoff | textwarn */ static const char *ztflag = NULL; --- 101,129 ---- static Setstate Bdflag = SET_UNKNOWN; static Setstate zfwflag = SET_UNKNOWN; static Boolean aflag = FALSE; static Boolean bflag = FALSE; static Boolean sflag = FALSE; static Boolean zinflag = FALSE; static Boolean zlflag = FALSE; static Boolean Bgflag = FALSE; static Boolean Blflag = FALSE; static Boolean Beflag = FALSE; static Boolean Bsflag = FALSE; static Boolean Dflag = FALSE; static Boolean Vflag = FALSE; + enum output_type { + OT_RELOC, /* relocatable object */ + OT_SHARED, /* shared object */ + OT_EXEC, /* dynamic executable */ + OT_KMOD, /* kernel module */ + }; + + static enum output_type otype = OT_EXEC; + /* * ztflag's state is set by pointing it to the matching string: * text | textoff | textwarn */ static const char *ztflag = NULL;
*** 226,235 **** --- 233,243 ---- (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZSCAP)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTARG)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZT)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTO)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTW)); + (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTY)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZWRAP)); (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZVER)); } /*
*** 311,332 **** if (Plibpath && (Llibdir || Ulibdir)) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_YP), Llibdir ? 'L' : 'U'); ! if (rflag) { if (dflag == SET_UNKNOWN) dflag = SET_FALSE; /* * Combining relocations when building a relocatable * object isn't allowed. Warn the user, but proceed. */ ! if (ofl->ofl_flags & FLG_OF_COMREL) ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_MARG_INCOMP), ! MSG_INTL(MSG_MARG_REL), MSG_ORIG(MSG_ARG_ZCOMBRELOC)); ofl->ofl_flags |= FLG_OF_RELOBJ; } else { /* * Translating object capabilities to symbol capabilities is * only meaningful when creating a relocatable object. */ --- 319,368 ---- if (Plibpath && (Llibdir || Ulibdir)) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_YP), Llibdir ? 'L' : 'U'); ! if ((otype == OT_RELOC) || (otype == OT_KMOD)) { ! if (otype == OT_RELOC) { if (dflag == SET_UNKNOWN) dflag = SET_FALSE; + if ((dflag == SET_TRUE) && + OFL_GUIDANCE(ofl, FLG_OFG_NO_KMOD)) { + ld_eprintf(ofl, ERR_GUIDANCE, + MSG_INTL(MSG_GUIDE_KMOD)); + } + } else if (otype == OT_KMOD) { + if (dflag != SET_UNKNOWN) { + ld_eprintf(ofl, ERR_FATAL, + MSG_INTL(MSG_MARG_INCOMP), + MSG_INTL(MSG_MARG_TYPE_KMOD), + MSG_ORIG(MSG_ARG_D)); + } + + dflag = SET_TRUE; + } + /* * Combining relocations when building a relocatable * object isn't allowed. Warn the user, but proceed. */ ! if (ofl->ofl_flags & FLG_OF_COMREL) { ! const char *msg; ! ! if (otype == OT_RELOC) { ! msg = MSG_INTL(MSG_MARG_REL); ! } else { ! msg = MSG_INTL(MSG_MARG_TYPE_KMOD); ! } ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_MARG_INCOMP), ! msg, MSG_ORIG(MSG_ARG_ZCOMBRELOC)); + } ofl->ofl_flags |= FLG_OF_RELOBJ; + + if (otype == OT_KMOD) + ofl->ofl_flags |= FLG_OF_KMOD; } else { /* * Translating object capabilities to symbol capabilities is * only meaningful when creating a relocatable object. */
*** 373,383 **** (FLG_OF1_NRLXREL | FLG_OF1_RLXREL)) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_ZRELAXRELOC), MSG_ORIG(MSG_ARG_ZNORELAXRELOC)); ! if (ofl->ofl_filtees && !Gflag) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_ONLYAVL), ((ofl->ofl_flags & FLG_OF_AUX) ? MSG_INTL(MSG_MARG_FILTER_AUX) : MSG_INTL(MSG_MARG_FILTER))); if (dflag != SET_FALSE) { --- 409,419 ---- (FLG_OF1_NRLXREL | FLG_OF1_RLXREL)) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_ZRELAXRELOC), MSG_ORIG(MSG_ARG_ZNORELAXRELOC)); ! if (ofl->ofl_filtees && (otype != OT_SHARED)) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_ONLYAVL), ((ofl->ofl_flags & FLG_OF_AUX) ? MSG_INTL(MSG_MARG_FILTER_AUX) : MSG_INTL(MSG_MARG_FILTER))); if (dflag != SET_FALSE) {
*** 427,437 **** } else if (ztflag == MSG_ORIG(MSG_ARG_ZTEXT)) { ofl->ofl_flags |= FLG_OF_PURETXT; ofl->ofl_guideflags |= FLG_OFG_NO_TEXT; } ! if (Gflag || !rflag) { /* * Create a dynamic object. -Bdirect indicates that all * references should be bound directly. This also * enables lazyloading. Individual symbols can be * bound directly (or not) using mapfiles and the --- 463,473 ---- } else if (ztflag == MSG_ORIG(MSG_ARG_ZTEXT)) { ofl->ofl_flags |= FLG_OF_PURETXT; ofl->ofl_guideflags |= FLG_OFG_NO_TEXT; } ! if ((otype == OT_SHARED) || (otype == OT_EXEC)) { /* * Create a dynamic object. -Bdirect indicates that all * references should be bound directly. This also * enables lazyloading. Individual symbols can be * bound directly (or not) using mapfiles and the
*** 467,477 **** FLG_OF1_NGLBDIR | FLG_OF1_ALNODIR); ofl->ofl_flags |= FLG_OF_SYMINFO; } } ! if (!Gflag && !rflag) { /* * Dynamically linked executable. */ ofl->ofl_flags |= FLG_OF_EXEC; --- 503,513 ---- FLG_OF1_NGLBDIR | FLG_OF1_ALNODIR); ofl->ofl_flags |= FLG_OF_SYMINFO; } } ! if (otype == OT_EXEC) { /* * Dynamically linked executable. */ ofl->ofl_flags |= FLG_OF_EXEC;
*** 491,501 **** MSG_ORIG(MSG_ARG_BSYMBOLIC)); if (ofl->ofl_soname) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_DY_INCOMP), MSG_INTL(MSG_MARG_SONAME)); ! } else if (!rflag) { /* * Shared library. */ ofl->ofl_flags |= FLG_OF_SHAROBJ; --- 527,537 ---- MSG_ORIG(MSG_ARG_BSYMBOLIC)); if (ofl->ofl_soname) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_DY_INCOMP), MSG_INTL(MSG_MARG_SONAME)); ! } else if (otype == OT_SHARED) { /* * Shared library. */ ofl->ofl_flags |= FLG_OF_SHAROBJ;
*** 541,550 **** --- 577,589 ---- ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_INCOMP), MSG_INTL(MSG_MARG_REL), MSG_ORIG(MSG_ARG_CI)); } + + assert((ofl->ofl_flags & (FLG_OF_SHAROBJ|FLG_OF_EXEC)) != + (FLG_OF_SHAROBJ|FLG_OF_EXEC)); } else { ofl->ofl_flags |= FLG_OF_STATIC; if (bflag) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
*** 562,579 **** ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP), MSG_ORIG(MSG_ARG_C)); if (ztflag) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP), MSG_ORIG(MSG_ARG_ZTEXTALL)); ! if (Gflag) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP), MSG_INTL(MSG_MARG_SO)); ! if (aflag && rflag) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_INCOMP), MSG_ORIG(MSG_ARG_A), MSG_INTL(MSG_MARG_REL)); ! if (rflag) { /* * We can only strip the symbol table and string table * if no output relocations will refer to them. */ if (sflag) --- 601,618 ---- ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP), MSG_ORIG(MSG_ARG_C)); if (ztflag) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP), MSG_ORIG(MSG_ARG_ZTEXTALL)); ! if (otype == OT_SHARED) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP), MSG_INTL(MSG_MARG_SO)); ! if (aflag && (otype == OT_RELOC)) ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_INCOMP), MSG_ORIG(MSG_ARG_A), MSG_INTL(MSG_MARG_REL)); ! if (otype == OT_RELOC) { /* * We can only strip the symbol table and string table * if no output relocations will refer to them. */ if (sflag)
*** 1199,1209 **** } break; case 'r': DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL)); ! rflag = TRUE; break; case 'R': DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg)); --- 1238,1248 ---- } break; case 'r': DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL)); ! otype = OT_RELOC; break; case 'R': DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
*** 1507,1516 **** --- 1546,1589 ---- */ } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASSDEFLIB), MSG_ARG_ASSDEFLIB_SIZE) == 0) { if (assdeflib_parse(ofl, optarg) != TRUE) return (S_ERROR); + + /* + * Process new-style output type specification, which + * we'll use in pass 2 and throughout. + */ + } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_TYPE), + MSG_ARG_TYPE_SIZE) == 0) { + char *p = optarg + MSG_ARG_TYPE_SIZE; + if (*p != '=') { + ld_eprintf(ofl, ERR_FATAL, + MSG_INTL(MSG_ARG_ILLEGAL), + MSG_ORIG(MSG_ARG_Z), optarg); + return (S_ERROR); + } + + p++; + if (strcmp(p, + MSG_ORIG(MSG_ARG_TYPE_RELOC)) == 0) { + otype = OT_RELOC; + } else if (strcmp(p, + MSG_ORIG(MSG_ARG_TYPE_EXEC)) == 0) { + otype = OT_EXEC; + } else if (strcmp(p, + MSG_ORIG(MSG_ARG_TYPE_SHARED)) == 0) { + otype = OT_SHARED; + } else if (strcmp(p, + MSG_ORIG(MSG_ARG_TYPE_KMOD)) == 0) { + otype = OT_KMOD; + } else { + ld_eprintf(ofl, ERR_FATAL, + MSG_INTL(MSG_ARG_ILLEGAL), + MSG_ORIG(MSG_ARG_Z), optarg); + return (S_ERROR); + } /* * The following options just need validation as they * are interpreted on the second pass through the * command line arguments. */
*** 1625,1635 **** } break; case 'G': DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL)); ! Gflag = TRUE; break; case 'L': DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg)); break; --- 1698,1708 ---- } break; case 'G': DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL)); ! otype = OT_SHARED; break; case 'L': DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg)); break;