Skip to content

linkerscript: fix ENTRY() last-wins - #1642

Open
Rachit Mehta (rachitmeht) wants to merge 2 commits into
qualcomm:mainfrom
rachitmeht:fix/entry-cmd-last-wins-precedence
Open

linkerscript: fix ENTRY() last-wins #1642
Rachit Mehta (rachitmeht) wants to merge 2 commits into
qualcomm:mainfrom
rachitmeht:fix/entry-cmd-last-wins-precedence

Conversation

@rachitmeht

Copy link
Copy Markdown

EntryCmd::activate() guarded with hasEntry(), making the first ENTRY() win over later ones and allowing script ENTRY() to overwrite a -e value set on the command line.

Similar to GNU ld, replace the guard with !isEntryFromCmdLine() so each ENTRY() overwrites the previous (last wins), while -e is always preserved regardless of script processing order.

Add EntryCmdPrecedence.test covering: last-wins within one script, -e override, last -e wins, raw-address -e 0, cross-script last-wins, and -e placed before -T.

Resolves #1538

Comment thread include/eld/Config/GeneralOptions.h
Comment thread lib/Script/EntryCmd.cpp Outdated
CurModule.getConfig().options().setEntry(EntrySymbol);
GeneralOptions &Options = CurModule.getConfig().options();
if (!EntrySymbol.empty() && !Options.isEntryFromCmdLine())
Options.setEntry(EntrySymbol);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do we handle

ld.eld -e -T <script>

and the script has ENTRY ?

Can we add a warning with -Wlinker-script when we see multiple ENTRY commands mentioned in the link line either in command line or linker script ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is handled similarly, how GNU ld handles, the command line -e will always take precedence, irrespective of linker script's ENTRY(). To keep track of this we need bool EntryFromCmdLine.
For multiple -e currently last one is considered

# Case 4: -e with a raw address overrides script ENTRY().
# Case 5: Across multiple -T scripts, the last ENTRY() activated wins.
# Case 6: -e overrides script ENTRY() regardless of command-line order
# (i.e. -e placed before -T still wins).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document this as well.

Comment thread lib/LinkerWrapper/GnuLdDriver.cpp Outdated
unsigned NumEntryArgs = 0;
for (auto *Arg : Args.filtered(T::entrypoint))
++NumEntryArgs;
if (NumEntryArgs > 1 && Config.showLinkerScriptWarnings())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is multiple -e command-line options part of the linker script warnings?

Comment thread lib/LinkerWrapper/GnuLdDriver.cpp Outdated
Comment on lines +714 to +719
unsigned NumEntryArgs = 0;
for (auto *Arg : Args.filtered(T::entrypoint))
++NumEntryArgs;
if (NumEntryArgs > 1 && Config.showLinkerScriptWarnings())
Config.raise(Diag::warn_multiple_entry);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think we should warn for multiple -e options, and if we should, then it should be under some command-line warning category.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understood the warning should be under -Wcommand-line, but if we are warning on multiple ENTRY() then we should also warn for multiple -e. aren't they the same case?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but if we are warning on multiple ENTRY() then we should also warn for multiple -e. aren't they the same case?

They are similar for sure, but passing same options multiple times is well-defined (and often well-used) behavior. And if we are giving warning on multiple -e options, then we should likely do the same for other options as well which can be repeated and last one takes effect. This being said, I personally do not think we should report warning on repeated command-line options. Shankar Easwaran (@quic-seaswara) what do you think about it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rachit Mehta (@rachitmeht) for now can you please remove warning from here?

Comment thread lib/Script/EntryCmd.cpp
if ((!EntrySymbol.empty()) && (!(CurModule.getConfig().options().hasEntry())))
CurModule.getConfig().options().setEntry(EntrySymbol);
GeneralOptions &Options = CurModule.getConfig().options();
if (!EntrySymbol.empty()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it was part of the original code, but do you know if there is any valid case where EntrySymbol may be empty?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Syntactically we can pass ENTRY("") it will result in EntrySymbol.empty(),

lld do gives warning in this case but ld.eld and ld.bfd silently ignores it

ld.lld: warning: cannot find entry symbol _start; not setting start address
  Entry point address:               0x0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting. We should also give warning for it. Can you please raise an issue for this?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ENTRY("") is treated as having no ENTRY() at all.
lld gives this warning if we have not specified an entry point at all.

EntryCmd::activate() guarded with hasEntry(), making the first ENTRY()
win over later ones and allowing script ENTRY() to overwrite a -e value
set on the command line.

Similar to GNU ld, replace the guard with !isEntryFromCmdLine() so
each ENTRY() overwrites the previous (last wins), while -e is always
preserved regardless of script processing order.

Add EntryCmdPrecedence.test covering: last-wins within one script,
-e override, last -e wins, raw-address -e 0, cross-script last-wins,
and -e placed before -T.

Resolves qualcomm#1538

Signed-off-by: Rachit Mehta <rachmeht@qti.qualcomm.com>
Add EntryCmdWarn.test covering rules and warning behaviour.

Document entry point precedence and the new warning in linker_script.rst,
linker_faq.rst, and diagnostic_reports.rst.

Resolves qualcomm#1538

Signed-off-by: Rachit Mehta <rachmeht@qti.qualcomm.com>
@parth-07
Parth (parth-07) force-pushed the fix/entry-cmd-last-wins-precedence branch from 127d917 to 22086fe Compare August 20, 2026 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Last ENTRY command in the linker script should take affect

3 participants