[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 3/4] target/mips: Rewrite UHI errno_mips() using GHashTable
From: |
Philippe Mathieu-Daudé |
Subject: |
Re: [PATCH 3/4] target/mips: Rewrite UHI errno_mips() using GHashTable |
Date: |
Sun, 4 Jul 2021 20:44:45 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 |
On 7/4/21 8:38 PM, Thomas Huth wrote:
> On 04/07/2021 19.07, Philippe Mathieu-Daudé 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é <f4bug@amsat.org>
>> ---
>> target/mips/tcg/sysemu/mips-semi.c | 62 ++++++++++++++++++++++--------
>> 1 file changed, 45 insertions(+), 17 deletions(-)
>> +static void uhi_errno_init(void)
>> +{
>> + gboolean ret = TRUE;
>> +
>> + uhi_errno_hash_table = g_hash_table_new(NULL, NULL);
>> +
>> + /*
>> + * Unified Hosting Interface (rev 1.1.6)
>> + * Appendix A. "Error values"
>> + */
>> + uhi_errno_insert(ENAMETOOLONG, 91);
>> #ifdef ELOOP
>> - [ELOOP] = 92,
>> + uhi_errno_insert(ELOOP, 92);
>> #endif
>> -};
>> +#ifdef EOVERFLOW
>> + uhi_errno_insert(EOVERFLOW, 139);
>> +#endif
>> + assert(ret == TRUE);
>> +}
>> 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 */
>> }
>
> Why not simply use a switch-case statement instead? ... that's simpler
> and still allows to compiler to optimize if the errno values are in a
> compact range.
I was expecting the #ifdef'ry to be ugly, but there isn't that many
actually. Sigh :(