[FFmpeg-devel] Patch for Mac OS X assembly-language support in trunk/libavcodec/fft_altivec_s.S

Paul Sterne make4ppc
Mon Jul 19 00:06:03 CEST 2010


This patch adds support to *libavcodec/fft_altivec_s.S* for the Mac OS X ppc
and ppc64 architectures, which use the mach-o binary executable file format
instead of ELF.
ELF-only code is separated from mach-o-only code using *#ifdef __APPLE__*or
*#ifndef __APPLE__*

Question -- where would we save the discussion below?  It seems too verbose
for source code comments and could conceptually apply to other
assembly-language code, yet the code may be difficult to understand without
it.

The mach-o file format does not have a global offset table.  Instead, a
"section difference" calculation must be performed to address data outside
of the text section.

There are separate variations of the section difference calculation used in
*libavcodec/fft_altivec_s.S* for locally defined and externally defined
symbols.

For locally defined symbols such as *fft_data*, the target register *r6* is
loaded with the relocatable 32-bit expression *
fft_data-<base_location_symbol>(r2)*.
The *<base_location_symbol>* represents the instruction address in the text
section where the base register *r2* is to be loaded with the run-time
address of that instruction by the *apple_ppc_pic_sect_diff_base* macro in *
libavcodec/asm.S*.
The immediate operands in the powerpc architecture are only 16 bits, thus
two instructions are required by the mach-o version of the *movrel* macro
in *libavcodec/asm.S* to load the value of the expression into the target
register:  The upper 16 bits are loaded using the *addis* instruction, and
the lower 16 bits are loaded with the *la* instruction which is a shortened
form of the *addi* instruction.

Behind the scenes, the assembler *as*, static linker *ld* and dynamic loader
*dyld* all work together to assign the appropriate value to the symbol *
fft_data*.  After assembly, the value of *fft_data* is its address relative
to the beginning of the text section's code in the object file.  The
assembler also creates relocation entries for the pair of *addis* and
*addi* instructions
which associates those instructions with the *fft_data* symbol and the
subtraction of the value of the *<base_location_symbol>*.

The static linker gathers together all symbols in the same section as *
fft_data* and aligns them to a section boundary within the *__DATA* segment
which is aligned to a page boundary, thus relocating the *fft_data* symbol.
 The static linker then uses the relocated value of the *fft_data* symbol
and the subtraction of the value of the *<base_location_symbol>* in the
relocation entry to modify the value of the relocatable expression used by
the *addis* and *addi* instructions.  The relocation entry is usually
discarded by the static linker because it is not needed by the dynamic
loader.

At execution time, the address of the shared object ("dynamic library" in
Apple's terminology) code could vary depending on the dynamic loader, but no
further modification is needed because the section difference calculation
already expects the address of the base location to loaded into the base
register *r2*.

For externally defined symbols such as *ff_cos_tabs*, it may not be possible
to know the value of the symbol until run-time because it may be externally
defined in a different shared object, plug-in or program.  Therefore,
storage for a pointer that will contain the value of an externally defined
symbol such as *ff_cos_tabs* is reserved in the *__nl_symbol_ptr* section of
the *__DATA* segment using the *.non_lazy_symbol_pointer* instruction later
followed by a *.long* for the ppc architecture or a *.quad* for the ppc64
architecture according to the *PTR* macro in  *libavcodec/asm.S*.  A locally
defined symbol *L_ff_cos_tabs$non_lazy_ptr* is assigned to that pointer,
which enables the value of the pointer to be loaded using the same
section-difference calculation as any other locally defined symbol*.*  The
pointer is associated with the externally defined symbol by the *
.indirect_symbol* pseudo-instruction, which the assembler uses to create a
relocation entry.

At run-time, the dynamic loader uses the relocation entry to store the value
of the externally defined symbol in the storage that was reserved for it by
the *PTR* macro and the *.indirect_symbol* pseudo-instruction.  In Apple's
terminology, that storage is known as a non-lazy symbol pointer, because the
dynamic loader must be "non-lazy" about resolving the value of the external
symbol.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: macosx_fft_altivec.patch
Type: application/octet-stream
Size: 3909 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100718/c4301e22/attachment.obj>



More information about the ffmpeg-devel mailing list