On 7/4/21 7:25 PM, Peter Maydell wrote:
> On Sun, 4 Jul 2021 at 18:07, Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
>>
>> Linking on Haiku OS fails:
>>
>>   
>> /boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/8.3.0/../../../../x86_64-unknown-haiku/bin/ld:
>>   error: 
>> libqemu-mips-softmmu.fa.p/target_mips_tcg_sysemu_mips-semi.c.o(.rodata) is 
>> too large (0xffff405a bytes)
>>   
>> /boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/8.3.0/../../../../x86_64-unknown-haiku/bin/ld:
>>   final link failed: memory exhausted
>>   collect2: error: ld returned 1 exit status
>>
>> This is because the host_to_mips_errno[] uses errno as index,
>> for example:
>>
>>   static const uint16_t host_to_mips_errno[] = {
>>       [ENAMETOOLONG] = 91,
>>       ...
>>
>> and Haiku defines [*] ENAMETOOLONG as:
>>
>>    12 /* Error baselines */
>>    13 #define B_GENERAL_ERROR_BASE              INT_MIN
>>    ..
>>    22 #define B_STORAGE_ERROR_BASE              (B_GENERAL_ERROR_BASE + 
>> 0x6000)
>>   ...
>>   106 #define B_NAME_TOO_LONG                   (B_STORAGE_ERROR_BASE + 4)
>>   ...
>>   211 #define ENAMETOOLONG                      
>> B_TO_POSIX_ERROR(B_NAME_TOO_LONG)
>>
>> so the array ends up beeing indeed too big.
>>
>> Since POSIX errno can't be use as indexes on Haiku,
>> rewrite errno_mips() using a GHashTable.
>>
>> [*] 
>> https://github.com/haiku/haiku/blob/r1beta3/headers/os/support/Errors.h#L130
>>
>> Signed-off-by: Philippe Mathieu-Daudé <f4...@amsat.org>
>> ---
>>  target/mips/tcg/sysemu/mips-semi.c | 62 ++++++++++++++++++++++--------
>>  1 file changed, 45 insertions(+), 17 deletions(-)
> 
>>  static int errno_mips(int host_errno)
>>  {
>> -    if (host_errno < 0 || host_errno >= ARRAY_SIZE(host_to_mips_errno)) {
>> -        return EINVAL;
>> -    } else if (host_to_mips_errno[host_errno]) {
>> -        return host_to_mips_errno[host_errno];
>> -    } else {
>> -        return host_errno;
>> +    gpointer uhi_errno;
>> +
>> +    if (uhi_errno_hash_table == NULL) {
>> +        uhi_errno_init();
>>      }
>> +
>> +    if (host_errno == 0) {
>> +        return 0;
>> +    }
>> +    if (g_hash_table_lookup_extended(uhi_errno_hash_table,
>> +                                     GINT_TO_POINTER(host_errno),
>> +                                     NULL, &uhi_errno)) {
>> +        return GPOINTER_TO_INT(uhi_errno);
>> +    }
>> +    return EINVAL; /* Not reachable per the specification */
> 
> Per whose specification? This function is passed the errno as set
> by various host OS functions like open(), lseek(), read(). POSIX allows
> those functions to set errno to any value, so this "we don't know
> a guest errno value for that" code is definitely reachable.

You are right, it is reachable. What I meant is other errnos are
not expected, and returning EINVAL for them doesn't seem ideal,
but the spec doesn't define a particular errno for unsupported
errnos. I'll reword as "Unsupported errno is not specified, use EINVAL".

Reply via email to