Skip to content

Commit

Permalink
Add --entry option to linker cli utility.
Browse files Browse the repository at this point in the history
  • Loading branch information
windelbouwman committed Jan 9, 2020
1 parent c078ba4 commit 0043061
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
29 changes: 24 additions & 5 deletions ppci/binutils/linker.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def link(
debug=False,
extra_symbols=None,
libraries=None,
entry=None,
):
""" Links the iterable of objects into one using the given layout.
Expand All @@ -33,6 +34,7 @@ def link(
extra_symbols: a dict of extra symbols which can be used during
linking.
libraries: a list of libraries to use when searching for symbols.
entry: the entry symbol where execution should begin.
Returns:
The linked object file
Expand Down Expand Up @@ -72,6 +74,7 @@ def link(
debug=debug,
extra_symbols=extra_symbols,
libraries=libraries,
entry_symbol_name=entry,
)
return output_obj

Expand All @@ -95,6 +98,7 @@ def link(
debug=False,
extra_symbols=None,
libraries=None,
entry_symbol_name=None,
):
""" Link together the given object files using the layout """
assert isinstance(input_objects, (list, tuple))
Expand All @@ -111,9 +115,18 @@ def link(
if debug:
self.dst.debug_info = DebugInfo()

# Take entry symbol from layout if not specified alreay:
if not entry_symbol_name and layout and layout.entry:
# TODO: what to do if two symbols are defined?
# for now the symbol given via command line overrides
# the entry in the linker script.
entry_symbol_name = layout.entry.symbol_name

# Define entry symbol:
if layout and layout.entry:
self.dst.entry_symbol_id = self.inject_symbol(layout.entry.symbol_name, 'global', None, None).id
if entry_symbol_name:
self.dst.entry_symbol_id = self.inject_symbol(
entry_symbol_name, "global", None, None
).id

# Define extra symbols:
extra_symbols = extra_symbols or {}
Expand Down Expand Up @@ -243,10 +256,12 @@ def inject_object(self, obj, debug):
# Merge entry symbol:
if obj.entry_symbol_id is not None:
if self.dst.entry_symbol_id is None:
self.dst.entry_symbol_id = symbol_id_mapping[obj.entry_symbol_id]
self.dst.entry_symbol_id = symbol_id_mapping[
obj.entry_symbol_id
]
else:
# TODO: improve error message?
raise CompilerError('Multiple entry points defined')
raise CompilerError("Multiple entry points defined")

# Merge debug info:
if debug and obj.debug_info:
Expand Down Expand Up @@ -593,7 +608,11 @@ def count_holes(offset, holes):

def do_relocations(self):
""" Perform the correct relocation as listed """
self.logger.debug("Performing {} linker relocations".format(len(self.dst.relocations)))
self.logger.debug(
"Performing {} linker relocations".format(
len(self.dst.relocations)
)
)
for reloc in self.dst.relocations:
self._do_relocation(reloc)

Expand Down
29 changes: 22 additions & 7 deletions ppci/cli/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,17 @@
"-g", help="retain debug information", action="store_true", default=False
)
parser.add_argument(
'--relocatable',
"-r", help="Generate relocatable output", action="store_true", default=False
"--relocatable",
"-r",
help="Generate relocatable output",
action="store_true",
default=False,
)
parser.add_argument(
"--entry",
"-e",
help="Use entry as the starting symbol of execution of the program.",
default=None,
)


Expand All @@ -48,24 +57,30 @@ def link(args=None):
args = parser.parse_args(args)
relocatable = args.relocatable
with LogSetup(args):
obj = api.link(args.obj, layout=args.layout, debug=args.g, partial_link=relocatable)
obj = api.link(
args.obj,
layout=args.layout,
debug=args.g,
partial_link=relocatable,
entry=args.entry,
)
if relocatable:
with open(args.output, "w") as output:
obj.save(output)
else:
create_platform_executable(obj, args.output)


def create_platform_executable(obj, output_filename):
""" Produce platform binary by spitting out exe/elf file. """
if sys.platform == 'linux':
if sys.platform == "linux":
executable_filename = output_filename
api.objcopy(obj, None, 'elf', executable_filename)
api.objcopy(obj, None, "elf", executable_filename)
else:
# TODO: create windows exe.
# raise NotImplementedError('Executable output not support for platform: {}'.format(sys.platform))
executable_filename = output_filename
api.objcopy(obj, None, 'elf', executable_filename)
api.objcopy(obj, None, "elf", executable_filename)


if __name__ == "__main__":
Expand Down

0 comments on commit 0043061

Please sign in to comment.