mirror of
https://github.com/mikpe/pdp10-tools.git
synced 2026-05-03 06:29:10 +00:00
ld_assign: cleanups
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
%%% -*- erlang-indent-level: 2 -*-
|
%%% -*- erlang-indent-level: 2 -*-
|
||||||
%%%
|
%%%
|
||||||
%%% Assigning addresses for pdp10-elf-ld
|
%%% Assigning addresses for pdp10-elf ld
|
||||||
%%% Copyright (C) 2020 Mikael Pettersson
|
%%% Copyright (C) 2020-2023 Mikael Pettersson
|
||||||
%%%
|
%%%
|
||||||
%%% This file is part of pdp10-tools.
|
%%% This file is part of pdp10-tools.
|
||||||
%%%
|
%%%
|
||||||
@@ -17,6 +17,11 @@
|
|||||||
%%%
|
%%%
|
||||||
%%% You should have received a copy of the GNU General Public License
|
%%% You should have received a copy of the GNU General Public License
|
||||||
%%% along with pdp10-tools. If not, see <http://www.gnu.org/licenses/>.
|
%%% along with pdp10-tools. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
%%%
|
||||||
|
%%%=============================================================================
|
||||||
|
%%%
|
||||||
|
%%% Finalize the Phdrs for the PT_LOAD segments by assigning virtual addresses
|
||||||
|
%%% and segment offsets.
|
||||||
|
|
||||||
-module(ld_assign).
|
-module(ld_assign).
|
||||||
|
|
||||||
@@ -25,24 +30,27 @@
|
|||||||
|
|
||||||
-include("ld_internal.hrl").
|
-include("ld_internal.hrl").
|
||||||
|
|
||||||
%% Output ======================================================================
|
%% Assign addresses and offsets to PT_LOAD segments ============================
|
||||||
|
|
||||||
-spec assign([#segment{}]) -> [#segment{}].
|
-spec assign([#segment{}]) -> [#segment{}].
|
||||||
assign(Segments) ->
|
assign(Segments) ->
|
||||||
%% TODO: assumes KL10B-compatible "small" code model output
|
|
||||||
VAddr = 8#00001001000 bsl 2, % section 1, page 1
|
|
||||||
PhNum = length(Segments),
|
PhNum = length(Segments),
|
||||||
true = PhNum < ?PN_XNUM, % assert; TODO: otherwise store PhNum in Shdr0.sh_info
|
true = PhNum < ?PN_XNUM, % assert; TODO: otherwise store PhNum in Shdr0.sh_info
|
||||||
|
%% TODO: assumes KL10B-compatible "small" code model output
|
||||||
|
VAddr = 8#00001001000 bsl 2, % section 1, page 1, word address to byte address
|
||||||
Offset = ?ELF36_EHDR_SIZEOF + ?ELF36_PHDR_SIZEOF * PhNum,
|
Offset = ?ELF36_EHDR_SIZEOF + ?ELF36_PHDR_SIZEOF * PhNum,
|
||||||
assign(Segments, Offset, VAddr, []).
|
{_Offset, _VAddr, NewSegments} = lists:foldl(fun assign/2, {Offset, VAddr, []}, Segments),
|
||||||
|
lists:reverse(NewSegments).
|
||||||
|
|
||||||
assign(_Segments = [], _Offset, _VAddr, NewSegments) -> lists:reverse(NewSegments);
|
assign(Segment, {Offset, VAddr, NewSegments}) ->
|
||||||
assign([Segment | Segments], Offset, VAddr, NewSegments) ->
|
|
||||||
#segment{phdr = Phdr} = Segment,
|
#segment{phdr = Phdr} = Segment,
|
||||||
#elf36_Phdr{p_filesz = FileSz, p_memsz = MemSz, p_align = Align} = Phdr,
|
#elf36_Phdr{p_filesz = FileSz, p_memsz = MemSz, p_align = Align} = Phdr,
|
||||||
SegAlign = max(4096, Align), % align to page boundary; TODO: target-specific
|
SegAlign = max(4096, Align), % align to page boundary; TODO: target-specific
|
||||||
SegOffset = (Offset + (SegAlign - 1)) band bnot (SegAlign - 1),
|
SegOffset = align(Offset, SegAlign),
|
||||||
SegVAddr = (VAddr + (SegAlign - 1)) band bnot (SegAlign - 1),
|
SegVAddr = align(VAddr, SegAlign),
|
||||||
NewPhdr = Phdr#elf36_Phdr{p_offset = SegOffset, p_vaddr = SegVAddr, p_align = SegAlign},
|
NewPhdr = Phdr#elf36_Phdr{p_offset = SegOffset, p_vaddr = SegVAddr, p_align = SegAlign},
|
||||||
NewSegment = Segment#segment{phdr = NewPhdr},
|
NewSegment = Segment#segment{phdr = NewPhdr},
|
||||||
assign(Segments, SegOffset + FileSz, SegVAddr + MemSz, [NewSegment | NewSegments]).
|
{SegOffset + FileSz, SegVAddr + MemSz, [NewSegment | NewSegments]}.
|
||||||
|
|
||||||
|
align(Offset, Alignment) ->
|
||||||
|
(Offset + (Alignment - 1)) band bnot (Alignment - 1).
|
||||||
|
|||||||
Reference in New Issue
Block a user